use std::mem;

// 值传递,传递一个数组的副本，副本的修改，不会影响原数组。
#[allow(dead_code)]
fn show_arr(arr: [String; 3]) {
    for item in arr.iter() {
        println!("{}", item)
    }
}

// 引用传递,传递内存的地址给函数，修改数组的任何值都会修改原来的数组。
#[allow(dead_code)]
fn modify_arr(arr: &mut [String; 3]) {
    let l = arr.len();
    for i in 0..l {
        // let string_value = int_value.to_string();//int to String
        // let back_int = string_value.parse::<i32>().unwrap();//String to int
        // let s = i.to_string();
        arr[i] = format!("item{:0>3?}", i);
    }
}

// 此函数借用一个切片。
#[allow(dead_code)]
fn analyze_slice(slice: &[i32]) {
    println!("切片的第一个元素：{}", slice[0]);
    println!("切片有 {} 个元素", slice.len());
}

fn main() {
    let arr01 = [
        String::from("Rust 入门指南"),
        "Rust 权威指南".to_string(),
        "Rust 系统开发".to_string(),
    ];
    println!("{}", arr01.len());
    println!("{}", arr01[0]);
    println!("--------");
    show_arr(arr01);

    let mut arr3 = [
        "Go语言极简一本通".to_string(),
        "Go语言微服务架构核心22讲".to_string(),
        "从0到Go语言微服务架构师".to_string(),
    ];
    print!("{:?}\n", arr3);
    modify_arr(&mut arr3);
    print!("{:?}\n", arr3);

    // 固定大小的数组（类型签名是多余的）。
    let xs: [i32; 5] = [1, 2, 3, 4, 5];

    // 所有元素可以初始化为相同的值。
    let ys: [i32; 500] = [0; 500];
    // 索引从 0 开始。
    println!("数组的第一个元素：{}", xs[0]);
    println!("数组的第二个元素：{}", xs[1]);
    // `len` 返回数组中元素的数量。
    println!("数组中的元素数量：{}", xs.len());
    // 数组是栈分配的。
    println!("数组占用 {} 字节", mem::size_of_val(&xs));
    // 数组可以自动借用为切片
    println!("将整个数组借用为切片.");
    analyze_slice(&xs);
    analyze_slice(&ys);

    // 切片可以指向数组的一部分。
    // 它们的形式是 [起始索引..结束索引].
    // `起始索引` 是切片中的第一个位置。
    // `结束索引` 是切片中最后一个位置的后一个位置。
    // 就是说，包含起始索引位置的值，但不包含结束索引位置的值
    println!("借用数组的一部分作为切片");
    analyze_slice(&xs[1..3]);
    analyze_slice(&ys[1..4]);

    // 空切片 `&[]` 的示例:
    let empty_array: [u32; 0] = [];
    assert_eq!(&empty_array, &[]);
    assert_eq!(&empty_array, &[][..]);

    // 可以使用 `.get` 安全地访问数组，它返回一个 `Option`。
    // 可以像下面这样对其进行匹配，或者使用 `.expect()`。
    // 如果你希望程序在访问越界时优雅地退出而不是继续执行，可以使用 `.expect()`。
    for i in 0..xs.len() + 1 {
        match xs.get(i) {
            Some(xval) => println!("{}: {}", i, xval),
            None => println!("慢着！ {} 超出范围了!", i),
        }
    }
}